#include "logicwork.h"

#include <session.h>

LogicWork::LogicWork()
{
}

void LogicWork::start()
{
	workThread_ = std::make_shared<std::thread>([&]() {
		bStop_ = false;
		while (!bStop_) {
			std::shared_ptr<LogicNode> logicNode;
			{
				std::unique_lock<std::mutex> locker(logicLock_);
				while (logicQueue_.size() == 0 && !bStop_) {
					logicCond_.wait(locker);
				}
				if (bStop_)break;
				assert(logicQueue_.size() > 0);
				logicNode = logicQueue_.front();
				logicQueue_.pop();
			}
			handler(logicNode);
		}
		}
	);
}

void LogicWork::stop()
{
	bStop_ = true;
	{
		std::lock_guard<std::mutex> locker(logicLock_);
		while (logicQueue_.size() > 0) {
			auto logicNode = logicQueue_.front();
			logicQueue_.pop();
			handler(logicNode);
		}
	}
	logicCond_.notify_all();
	workThread_->join();
}

bool LogicWork::postTask(std::shared_ptr<LogicNode> logicNode)
{
	{
		std::lock_guard<std::mutex> locker(logicLock_);
		if (logicQueue_.size() > MAX_QUEUE_SIZE) {
			std::cout << "logicQueue is fulled. size: " << logicQueue_.size()  << std::endl;
			return false;
		}
		logicQueue_.push(logicNode);
	}
	logicCond_.notify_one();
	return true;
}

void LogicWork::handler(std::shared_ptr<LogicNode> logicNode)
{
	auto recvNode = logicNode->recvNode_;
	// handler后面要实现成根据不同的msgId调用不同的处理函数
	int msgId = recvNode->msgId_;
	if (msgId == static_cast<int>(MsgType::TYPE_TEXT)) {
		std::shared_ptr<SendNode> sendNode = std::make_shared<SendNode>(recvNode->data_, recvNode->msgId_, recvNode->totalLen_);
		logicNode->session_->postSendNode(sendNode);
	}else {
		throw std::runtime_error("unknown msg type: " + std::to_string(msgId));
	}

	//QString str = QString::asprintf("msgid:%1 dataLen:%2 data:%3\n").arg(recvNode->msgId_).arg(recvNode->totalLen_).arg(recvNode->data_);
}

LogicWork::~LogicWork()
{}
